import mongoose, { Document, Schema, Model } from 'mongoose';
import bcrypt from 'bcryptjs';

/**
 * 用户接口定义
 * 定义用户的基本属性和方法
 */
export interface IUser extends Document {
  /** 用户名，唯一标识 */
  username: string;
  /** 邮箱地址，唯一标识 */
  email: string;
  /** 加密后的密码 */
  password: string;
  /** 真实姓名 */
  realName: string;
  /** 手机号码 */
  phone?: string;
  /** 头像URL */
  avatar?: string;
  /** 用户状态：active-激活，inactive-未激活，disabled-禁用 */
  status: 'active' | 'inactive' | 'disabled';
  /** 管理员级别：super-超级管理员，system-系统管理员，subsystem-子系统管理员，normal-普通管理员，user-普通用户 */
  adminLevel: 'super' | 'system' | 'subsystem' | 'normal' | 'user';
  /** 是否为超级管理员 */
  isSuperAdmin: boolean;
  /** 所属团队ID */
  teamId?: mongoose.Types.ObjectId;
  /** 所属部门ID */
  departmentId?: mongoose.Types.ObjectId;
  /** 所属小组ID */
  groupId?: mongoose.Types.ObjectId;
  /** 最后登录时间 */
  lastLoginAt?: Date;
  /** 最后登录IP */
  lastLoginIp?: string;
  /** 创建时间 */
  createdAt: Date;
  /** 更新时间 */
  updatedAt: Date;
  
  /**
   * 比较密码方法
   * @param candidatePassword 待比较的明文密码
   * @returns 密码是否匹配
   */
  comparePassword(candidatePassword: string): Promise<boolean>;
}

/**
 * 用户模型静态方法接口
 */
export interface IUserModel extends Model<IUser> {
  /**
   * 通过用户名查找用户
   * @param username 用户名
   * @returns 用户对象或null
   */
  findByUsername(username: string): Promise<IUser | null>;
  
  /**
   * 通过邮箱查找用户
   * @param email 邮箱地址
   * @returns 用户对象或null
   */
  findByEmail(email: string): Promise<IUser | null>;
  
  /**
   * 通过组织信息查找用户
   * @param organizationQuery 组织查询条件
   * @returns 用户列表
   */
  findByOrganization(organizationQuery: {
    teamId?: mongoose.Types.ObjectId;
    departmentId?: mongoose.Types.ObjectId;
    groupId?: mongoose.Types.ObjectId;
  }): Promise<IUser[]>;
  
  /**
   * 查找超级管理员
   * @returns 超级管理员用户或null
   */
  findSuperAdmin(): Promise<IUser | null>;
  
  /**
   * 通过管理员级别查找用户
   * @param adminLevel 管理员级别
   * @returns 用户列表
   */
  findByAdminLevel(adminLevel: 'super' | 'system' | 'subsystem' | 'normal' | 'user'): Promise<IUser[]>;
  
  /**
   * 创建超级管理员
   * @param userData 用户数据
   * @returns 创建的超级管理员用户
   */
  createSuperAdmin(userData: {
    username: string;
    email: string;
    password: string;
    realName: string;
  }): Promise<IUser>;
}

/**
 * 用户数据模型Schema定义
 * 定义用户在MongoDB中的数据结构和验证规则
 */
const UserSchema = new Schema<IUser>({
  // 用户名：必填，唯一，3-20个字符，只能包含字母数字下划线
  username: {
    type: String,
    required: [true, '用户名不能为空'],
    unique: true,
    trim: true,
    minlength: [3, '用户名至少3个字符'],
    maxlength: [20, '用户名最多20个字符'],
    match: [/^[a-zA-Z0-9_]+$/, '用户名只能包含字母、数字和下划线']
  },
  
  // 邮箱：必填，唯一，格式验证
  email: {
    type: String,
    required: [true, '邮箱不能为空'],
    unique: true,
    trim: true,
    lowercase: true,
    match: [/^[^\s@]+@[^\s@]+\.[^\s@]+$/, '邮箱格式不正确']
  },
  
  // 密码：必填，加密存储
  password: {
    type: String,
    required: [true, '密码不能为空'],
    minlength: [6, '密码至少6个字符']
  },
  
  // 真实姓名：必填
  realName: {
    type: String,
    required: [true, '真实姓名不能为空'],
    trim: true,
    maxlength: [50, '真实姓名最多50个字符']
  },
  
  // 手机号码：可选，格式验证
  phone: {
    type: String,
    trim: true,
    match: [/^1[3-9]\d{9}$/, '手机号码格式不正确']
  },
  
  // 头像URL：可选
  avatar: {
    type: String,
    trim: true
  },
  
  // 用户状态：默认为active
  status: {
    type: String,
    enum: {
      values: ['active', 'inactive', 'disabled'],
      message: '用户状态必须是 active、inactive 或 disabled'
    },
    default: 'active'
  },
  
  // 管理员级别：默认为普通用户
  adminLevel: {
    type: String,
    enum: {
      values: ['super', 'system', 'subsystem', 'normal', 'user'],
      message: '管理员级别必须是 super、system、subsystem、normal 或 user'
    },
    default: 'user'
  },
  
  // 是否为超级管理员：默认为false
  isSuperAdmin: {
    type: Boolean,
    default: false
  },
  
  // 组织架构关联
  teamId: {
    type: Schema.Types.ObjectId,
    ref: 'Team'
  },
  
  departmentId: {
    type: Schema.Types.ObjectId,
    ref: 'Department'
  },
  
  groupId: {
    type: Schema.Types.ObjectId,
    ref: 'Group'
  },
  
  // 登录相关信息
  lastLoginAt: {
    type: Date
  },
  
  lastLoginIp: {
    type: String,
    trim: true
  }
}, {
  // 自动添加创建时间和更新时间
  timestamps: true,
  // 转换为JSON时的配置
  toJSON: {
    transform: function(doc, ret) {
      // 删除密码字段，确保不会在API响应中暴露
      const { password, ...result } = ret;
      return result;
    }
  }
});

/**
 * 密码加密中间件
 * 在保存用户前自动加密密码
 */
UserSchema.pre<IUser>('save', async function(next) {
  // 如果密码没有被修改，跳过加密
  if (!this.isModified('password')) {
    return next();
  }
  
  try {
    // 生成盐值并加密密码
    const salt = await bcrypt.genSalt(12);
    this.password = await bcrypt.hash(this.password, salt);
    next();
  } catch (error) {
    next(error as Error);
  }
});

/**
 * 实例方法：比较密码
 * 用于登录时验证用户输入的密码是否正确
 */
UserSchema.methods.comparePassword = async function(candidatePassword: string): Promise<boolean> {
  try {
    return await bcrypt.compare(candidatePassword, this.password);
  } catch (error) {
    return false;
  }
};

/**
 * 静态方法：通过用户名查找用户
 * @param username 用户名
 * @returns 用户对象或null
 */
UserSchema.statics.findByUsername = function(username: string): Promise<IUser | null> {
  return this.findOne({ username }).exec();
};

/**
 * 静态方法：通过邮箱查找用户
 * @param email 邮箱地址
 * @returns 用户对象或null
 */
UserSchema.statics.findByEmail = function(email: string): Promise<IUser | null> {
  return this.findOne({ email: email.toLowerCase() }).exec();
};

/**
 * 通过组织信息查找用户的静态方法实现
 * @param organizationQuery 组织查询条件
 * @returns 用户列表
 */
UserSchema.statics.findByOrganization = function(organizationQuery: {
  teamId?: mongoose.Types.ObjectId;
  departmentId?: mongoose.Types.ObjectId;
  groupId?: mongoose.Types.ObjectId;
}): Promise<IUser[]> {
  const query: any = {};
  
  if (organizationQuery.teamId) {
    query.teamId = organizationQuery.teamId;
  }
  if (organizationQuery.departmentId) {
    query.departmentId = organizationQuery.departmentId;
  }
  if (organizationQuery.groupId) {
    query.groupId = organizationQuery.groupId;
  }
  
  return this.find(query).exec();
};

/**
 * 查找超级管理员的静态方法实现
 * @returns 超级管理员用户或null
 */
UserSchema.statics.findSuperAdmin = function(): Promise<IUser | null> {
  return this.findOne({ isSuperAdmin: true, adminLevel: 'super' }).exec();
};

/**
 * 通过管理员级别查找用户的静态方法实现
 * @param adminLevel 管理员级别
 * @returns 用户列表
 */
UserSchema.statics.findByAdminLevel = function(adminLevel: 'super' | 'system' | 'subsystem' | 'normal' | 'user'): Promise<IUser[]> {
  return this.find({ adminLevel }).exec();
};

/**
 * 创建超级管理员的静态方法实现
 * @param userData 用户数据
 * @returns 创建的超级管理员用户
 */
UserSchema.statics.createSuperAdmin = async function(userData: {
  username: string;
  email: string;
  password: string;
  realName: string;
}): Promise<IUser> {
  // 检查是否已存在超级管理员
  const existingSuperAdmin = await (this as IUserModel).findSuperAdmin();
  if (existingSuperAdmin) {
    throw new Error('超级管理员已存在，不能重复创建');
  }
  
  // 创建超级管理员用户
  const superAdminData = {
    ...userData,
    adminLevel: 'super' as const,
    isSuperAdmin: true,
    status: 'active' as const
  };
  
  return this.create(superAdminData);
};

/**
 * 创建并导出用户模型
 */
export const User = mongoose.model<IUser, IUserModel>('User', UserSchema);

// 默认导出
export default User;